import time

from selenium import webdriver
from selenium.webdriver import Keys
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager

from lxml import etree

from utils import get_integer_input, clear_screen, Menu


class Spider_driver:
    def __init__(self, login_url):
        menu = Menu()
        # 初始化自动化爬虫
        # 配置参数
        self.last_url = None
        # 主页面url
        self.main_url = None
        self.name = None
        self.menu = menu
        self.last_menu = Menu()
        self.bottom_list =[]
        chrome_options = Options()
        # 设置 Chrome 的日志级别为 ERROR，只显示错误信息
        chrome_options.add_experimental_option('excludeSwitches', ['enable-logging'])
        # 忽略证书错误
        chrome_options.add_argument('--ignore-certificate-errors')
        chrome_options.add_argument("--headless")  # 启用无头模式，隐藏浏览器界面
        chrome_options.add_argument("--no-sandbox")  # 防止一些潜在问题
        chrome_options.add_argument('--disable-dev-shm-usage')
        chrome_options.add_argument("--window-size=1800,3000")  # 防止页面某些元素可能不被点到

        # 添加user-agent，避免被当作爬虫脚本,使得无头模式下能够正常爬取
        chrome_options.add_argument(
            "user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36")
        executable_path = ChromeDriverManager().install()  # 安装chrome驱动并自动获取地址返回
        # print(executable_path)
        # "C:\\Users\\sumengxian\\.wdm\\drivers\\chromedriver\\win64\\128.0.6613.137\\chromedriver-win32/chromedriver.exe"
        service = Service(
            executable_path=executable_path)
        self.driver = webdriver.Chrome(service=service, options=chrome_options)  # 得到驱动器
        self.login_url = login_url

    def login(self):
        clear_screen()
        username = input("请输入用户名: ")
        password = input("请输入密码: ")
        try:
            self.driver.get(self.login_url)
            while "data;" in self.driver.current_url:
                self.driver.get(self.login_url)
        except:
            print("网络异常")
            return False
        login_nodes = self.driver.find_elements(By.XPATH, '//input')
        # 清除输入框中的默认文本（如果有的话）
        self.driver.execute_script("arguments[0].value='';", login_nodes[0])
        self.driver.execute_script("arguments[0].value='';", login_nodes[1])
        # 输入用户
        login_nodes[0].send_keys(username)
        # 输入密码
        login_nodes[1].send_keys(password)
        # 模拟回车键
        login_nodes[1].send_keys(Keys.RETURN)
        time_error = 0
        while self.login_url == self.driver.current_url:
            time_error += 1
            time.sleep(0.5)
            if time_error > 10:
                print("登录失败,请重试")
                return False
        self.last_url = self.driver.current_url
        # 记住主页面
        self.main_url = self.driver.current_url
        # # 尝试获取用户信息
        # self.driver.get("https://www.ketangpai.com/#/main/UserSetting")
        # while self.last_url == self.driver.current_url:
        #     time.sleep(0.5)
        # self.last_url = self.driver.current_url
        # print(self.driver.current_url)
        # name_tags = self.driver.find_elements(By.XPATH, '//*[@id="app"]/div[3]/div[1]/div[2]/h6')
        # while len(name_tags) == 0:
        #     name_tags = self.driver.find_elements(By.XPATH, '//*[@id="app"]/div[3]/div[1]/div[2]/h6')
        # self.name = name_tags[0].text
        self.menu.add_information(f"用户已登录")
        self.menu.delete_options(["登录"])
        self.menu.add_option("获取代办事项")
        self.menu.add_option("退出登录")
        self.last_menu = self.menu.copy()
        return True

    # 获取列表
    def page_list(self):
        self.driver.get(self.main_url)
        time.sleep(0.5)
        self.last_url = self.driver.current_url
        next_buttons = self.driver.find_elements(By.XPATH, "//*[contains(@class, 'right common_pointer')]")
        while len(next_buttons) == 0:
            next_buttons = self.driver.find_elements(By.XPATH, "//*[contains(@class, 'right common_pointer')]")
        # 跳转到任务列表
        self.driver.execute_script("arguments[0].click();", next_buttons[0])

        while self.last_url == self.driver.current_url:
            time.sleep(0.5)
        time.sleep(0.5)
        node = etree.HTML(self.driver.page_source)
        options_list = node.xpath("//*[contains(@class, 'tabs-box flex-between')]")[0]
        node = options_list.getchildren()[0]
        child_options = []
        child_xpath_list = []
        for child in node.getchildren():
            child_xpath = node.getroottree().getpath(child)
            child_options.append(child.text)
            child_xpath_list.append(child_xpath)
        self.menu.reset_options(child_options)
        self.menu.add_option("返回")
        self.bottom_list = child_xpath_list
    # 返回初始菜单
    def back(self):
        self.menu = self.last_menu.copy()
        self.menu.display()
    # 重置
    def reset(self):
        # 配置参数
        self.last_url = None
        # 主页面url
        self.main_url = None
        self.name = None
        self.bottom_list = []

    def controller(self):
        spider_error = True
        while spider_error:
            spider_error = False
            # 定义选项列表
            options = ["登录", "设置"]

            # 显示菜单选项并输入选择
            self.menu.reset_options(options)
            options_index = self.menu.display_and_input()

            if self.menu.get_options()[options_index] == "登录":
                if not self.login():
                    spider_error = True
                    self.reset()
                    continue
                original_is_return = True
                while original_is_return:
                    original_is_return = False
                    options_index = self.menu.display_and_input()

                    if self.menu.get_options()[options_index] == "获取代办事项":
                        # 记录上一级菜单
                        previous_temporary_menus = []
                        # 记录上一级按钮集合
                        previous_temporary_bottoms = []
                        self.page_list()
                        is_return = True
                        while is_return:
                            is_return = False
                            # 点击进入具体列表页
                            options_index = self.menu.display_and_input()
                            if self.menu.get_options()[options_index] == "返回":
                                self.menu = self.last_menu.copy()
                                self.bottom_list = []
                                self.driver.get(self.last_url)
                                original_is_return = True
                                break
                            bottom_xpath = self.bottom_list[options_index]
                            bottom_list = self.driver.find_elements(By.XPATH, bottom_xpath)
                            while len(bottom_list) == 0:
                                bottom_list = len(self.driver.find_elements(By.XPATH, bottom_xpath))
                            self.driver.execute_script("arguments[0].click();", bottom_list[0])
                            time.sleep(0.5)
                            page_list_node = etree.HTML(self.driver.page_source)
                            now_page_list_text = []
                            now_page_list_bottom = []
                            for item in page_list_node.xpath('//*[@id="app"]/div[3]/div/div[2]')[0].getchildren()[0].getchildren():
                                now_page_list_text.append(''.join(item.itertext()).strip().replace('\n', '').strip())
                                now_page_list_bottom.append(page_list_node.getroottree().getpath(item))
                            previous_temporary_menus.append(self.menu.copy())
                            previous_temporary_bottoms.append(self.bottom_list)
                            self.menu.reset_options(now_page_list_text)
                            self.menu.add_option("返回")
                            self.bottom_list = now_page_list_bottom
                            if self.menu.get_options()[self.menu.display_and_input()] == "返回":
                                is_return = True
                                self.menu = previous_temporary_menus[-1].copy()
                                previous_temporary_menus.pop(-1)
                                self.bottom_list = previous_temporary_bottoms[-1]
                                previous_temporary_bottoms.pop(-1)
                                continue




